package ru.ksu.ktk.diploma.sdi.mapping;

import java.util.ArrayList;
import java.util.List;

/**
 * mapping element
 * 
 * @author NZhiltsov Time: 0:10:32
 */
public class MappingElement implements Comparable<MappingElement> {

    private static final String ELEMENT_INFO_PATTERN = "(%s) weight=%d";
    private static final String FULL_ELEMENT_PATTERN = "%s %s %s " + ELEMENT_INFO_PATTERN;
    /**
     * URI of source model class
     */
    private final String srcClassURI;
    /**
     * target triple
     */
    private final Triple targetTriple;
    /**
     * weight
     */
    private int weight;
    /**
     * index terms of thesauri
     */
    private final List<String> indexBlocks;
    /**
     * identifiers of terms found in source text
     */
    private final List<String> matchedDescriptors;

    public static class Builder {
        private final String srcClassURI;
        private final Triple targetTriple;
        private int weight = 0;
        private List<String> indexBlocks = new ArrayList<String>();
        private List<String> matchedDescriptors = new ArrayList<String>();

        public Builder(String srcClassURI, Triple targetTriple) {
            this.srcClassURI = srcClassURI;
            this.targetTriple = targetTriple;
        }

        public Builder weight(int weight) {
            this.weight = weight;
            return this;
        }

        public Builder indexBlocks(List<String> indexBlocks) {
            this.indexBlocks = indexBlocks;
            return this;
        }

        public Builder matchedDescriptors(List<String> matchedDescriptors) {
            this.matchedDescriptors = matchedDescriptors;
            return this;
        }

        public MappingElement build() {
            return new MappingElement(this);
        }

    }

    private MappingElement(Builder builder) {
        srcClassURI = builder.srcClassURI;
        targetTriple = builder.targetTriple;
        weight = builder.weight;
        indexBlocks = builder.indexBlocks;
        matchedDescriptors = builder.matchedDescriptors;
    }

    public String toString() {
        if (targetTriple != null){
            return String.format(FULL_ELEMENT_PATTERN, targetTriple.getDomainUri(), targetTriple.getPathUri(),
                targetTriple.getRangeUri(), srcClassURI, weight);
        }
        else{
            return String.format(ELEMENT_INFO_PATTERN, srcClassURI, weight);
        }

    }

    public int getWeight() {
        return weight;
    }

    public String getSrcClassURI() {
        return srcClassURI;
    }

    public Triple getTargetTriple() {
        return targetTriple;
    }

    public void addIndexBlock(String indexBlock) {
        if (indexBlock != null) indexBlocks.add(indexBlock);
    }

    public void addMatchedDescriptor(String descriptor) {
        if (descriptor != null) matchedDescriptors.add(descriptor);
    }

    public void increaseWeight(int weight) {
        this.weight += weight;
    }

    public int compareTo(MappingElement mappingElement) {
        if (mappingElement != null){
            int otherWeight = mappingElement.getWeight();
            if (weight > otherWeight) return 1;
            if (weight < otherWeight) return -1;
        }
        return 0;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof MappingElement)) return false;
        MappingElement mapEl = (MappingElement) o;
        return srcClassURI.equals(mapEl.getSrcClassURI()) && targetTriple.equals(mapEl.getTargetTriple());
    }

    @Override
    public int hashCode() {
        int result = 17;
        if (srcClassURI != null){
            result = 31 * result + srcClassURI.hashCode();
        }
        if (targetTriple != null){
            result = 31 * result + targetTriple.hashCode();
        }

        return result;

    }

}
